/***************************************************************************//**
 * @file stateMachine.h
 * @brief for common stateMachine
 * @author ze .
 * @date  2022/7/03.
 * @copyright Copyright 
 ******************************************************************************/

#ifndef _STATEMACHINE_H_
#define _STATEMACHINE_H_

#include <stdbool.h>
#include <stdint.h>
#include "stdio.h"

//事件结构体
typedef struct event // called in stateMachineRun();
{
   int type;
   void *data;
}STATEM_TYPE_ST;

typedef struct stateMachine
{
   struct state *currentState;
   struct state *previousState;
   struct state *errorState;
   void*       ctrlData;//该状态机内公共属性
}STATEM_STATE_MACHINE_ST;

//状态转移字段结构体
typedef struct transition
{
   int eventType;
   void *condition;
   bool ( *guard )(STATEM_STATE_MACHINE_ST* stateMachine, void *condition, struct event *event );//用于判断是否满足状态转移条件
   bool ( *action )(STATEM_STATE_MACHINE_ST* stateMachine , struct event *event );// @return isNextContinue, ==1 则直接跳转到下个状态执行
   struct state *nextState;
}STATEM_TRANSITION_ST;

//状态结构体
typedef struct state
{
   int   handle;
   struct transition *transitions;
   size_t numTransitions;
}STATEM_STATE_ST;


void stateM_init( struct stateMachine *fsm, struct state *initialState, struct state *errorState ,void* data);


typedef enum stateM_handleEventRetVals
{
   stateM_errArg = -2,
   stateM_errorStateReached,
   stateM_stateChanged,
   stateM_stateNextContinue, //  循环直接跳转到下一个状态执行 
   stateM_stateLoopSelf, // 
   stateM_noStateChange,
   //stateM_finalStateReached,
}STATE_MACHINE_HANDLE_RESULT_EN;

//需在主动函数，建议main函数内轮询调用，传入事件类型和数据
int stateM_handleEvent( struct stateMachine *fsm,struct event *event );

struct state *stateM_currentState( struct stateMachine *fsm );

struct state *stateM_previousState( struct stateMachine *fsm );

/**
 * @brief Check if the state machine has stopped
 *
 */
bool stateM_stopped( struct stateMachine *fsm );

#endif // STATEMACHINE_H


